/* eslint-disable @typescript-eslint/no-explicit-any */
"use client"

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Spinner } from "@/components/ui/kibo-ui/spinner"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Switch } from "@/components/ui/switch"
import { useQuery, useQueryClient } from "@tanstack/react-query"
import axios from "axios"
import { PlusCircle, Trash2 } from "lucide-react"
import { useState } from "react"
import { Controller, useFieldArray, useForm } from "react-hook-form"

const FIELD_TYPES = [
    { value: "text", label: "Text" },
    { value: "textarea", label: "Long Text" },
    { value: "richtext", label: "Rich Text" },
    { value: "number", label: "Number" },
    { value: "checkbox", label: "Checkbox" },
    { value: "select", label: "Select (Dropdown)" },
    { value: "radio", label: "Radio" },
    { value: "date", label: "Date" },
    { value: "image", label: "Image" },
    { value: "file", label: "File" },
    { value: "slug", label: "Slug" },
    { value: "relation", label: "Relation" },
]

type FieldOption = {
    label: string
    value: string
}

type Field = {
    name: string
    label: string
    type: string
    required: boolean
    options?: FieldOption[]
    description?: string
    relation?: {
        target: string
        relationType: "one-one" | "one-many" | "many-many"
    }
    slugSource?: string // For slug fields, source field to derive slug from
}

type ContentTypeForm = {
    name: string
    label: string
    fields: Field[]
}

export default function ContentTypeEditPage()
{
    const [isRestarting, setIsRestarting] = useState(false);
    // Query Clients
    const queryClient = useQueryClient()
    const { control, register, handleSubmit, reset, watch } = useForm<ContentTypeForm>({
        defaultValues: {
            name: "",
            label: "",
            fields: [],
        },
    })
    const { fields, append, remove } = useFieldArray({
        control,
        name: "fields",
    })

    const [apiError, setApiError] = useState<string | null>(null)
    const [submitting, setSubmitting] = useState(false)
    const [submitted, setSubmitted] = useState(false)

    const { data: contentTypeOptions = [] } = useQuery({
        queryKey: ["content-types"],
        queryFn: async () =>
        {
            const res = await axios.get("/api/content-types/list")
            return res.data as { value: string; label: string }[]
        }
    })

    async function onSubmit(data: ContentTypeForm)
    {
        setSubmitting(true)
        setSubmitted(false)
        setApiError(null)
        setIsRestarting(true)
        try {
            await axios.post("/api/content-types/create", data)
            setSubmitted(true)
            reset({ name: "", label: "", fields: [] })
        } catch (e: any) {
            setApiError(e?.response?.data?.error || "Failed to save content type")
        } finally {
            setTimeout(() =>
            {
                window.location.reload();
            }, 10000);
            setSubmitting(false)
            queryClient.invalidateQueries({ queryKey: ["content-types"] })
        }
    }

    function onAddField()
    {
        append({
            name: "",
            label: "",
            type: "text",
            required: false,
            options: [],
            description: "",
        })
    }

    const watchedFields = watch("fields")

    return (
        <div className="w-full pt-10 px-6">
            <div className="container">
                <h1 className="text-3xl font-bold mb-2">Content Type Builder</h1>
                <p className="text-muted-foreground mb-8">Design your custom content types visually, including field types and relations. No boxes, no borders—just space to think.</p>
                <form className="space-y-6" onSubmit={handleSubmit(onSubmit)}>
                    {/* Content Type Info */}
                    <div className="grid md:grid-cols-2 gap-6 pb-6 border-b">
                        <div>
                            <Label htmlFor="name" className="font-medium text-lg">Type Name</Label>
                            <Input
                                id="name"
                                className="mt-2 p-3 h-auto"
                                placeholder="Type name (no spaces, e.g. blogPost)"
                                {...register("name", {
                                    required: true,
                                    setValueAs: (v) =>
                                        v.trim().replace(/\s+/g, '_').replace(/[^a-zA-Z0-9_]/g, '').toLowerCase()
                                })}
                                autoCapitalize="none"
                            />
                        </div>
                        <div>
                            <Label htmlFor="label" className="font-medium text-lg">Type Label</Label>
                            <Input
                                id="label"
                                className="mt-2 p-3 h-auto"
                                placeholder="Display name (e.g. Blog Post)"
                                {...register("label", { required: true })}
                            />
                        </div>
                    </div>

                    {/* Fields Section */}
                    <section>
                        <div className="flex items-center justify-between pb-3">
                            <h2 className="text-xl font-semibold">Fields</h2>
                            <Button
                                type="button"
                                variant="default"
                                size="sm"
                                className="gap-2"
                                onClick={onAddField}
                            >
                                <PlusCircle className="w-4 h-4" /> Add Field
                            </Button>
                        </div>
                        <div className="flex flex-col gap-8">
                            {fields.length === 0 && (
                                <div className="text-muted-foreground italic mt-2">
                                    Add your first field.
                                </div>
                            )}
                            {fields.map((field, idx) => (
                                <div
                                    key={field.id}
                                    className="rounded-xl transition"
                                >
                                    <div className="grid grid-cols-1 md:grid-cols-10 gap-4">
                                        <div className="col-span-3 space-y-2">
                                            <Label>Label</Label>
                                            <Input
                                                placeholder="Field label (e.g. Title)"
                                                {...register(`fields.${idx}.label` as const, { required: true })}
                                            />
                                        </div>
                                        <div className="col-span-3 space-y-2">
                                            <Label>Name</Label>
                                            <Input
                                                placeholder="Field name (e.g. title)"
                                                {...register(`fields.${idx}.name` as const, { required: true })}
                                                autoCapitalize="none"
                                            />
                                        </div>
                                        <div className="col-span-2 space-y-2">
                                            <Label>Type</Label>
                                            <Controller
                                                control={control}
                                                name={`fields.${idx}.type` as const}
                                                render={({ field }) => (
                                                    <Select value={field.value} onValueChange={field.onChange}>
                                                        <SelectTrigger className="w-full">
                                                            <SelectValue placeholder="Select field type" />
                                                        </SelectTrigger>
                                                        <SelectContent>
                                                            {FIELD_TYPES.map((type) => (
                                                                <SelectItem key={type.value} value={type.value}>
                                                                    {type.label}
                                                                </SelectItem>
                                                            ))}
                                                        </SelectContent>
                                                    </Select>
                                                )}
                                            />
                                        </div>
                                        <div className="col-span-2 flex justify-around gap-2 items-center h-full">
                                            <div className="flex gap-2 ">
                                                <Controller
                                                    control={control}
                                                    name={`fields.${idx}.required` as const}
                                                    render={({ field }) => (
                                                        <Switch
                                                            className="cursor-pointer"
                                                            checked={field.value}
                                                            id={`field-${idx}-required`}
                                                            onCheckedChange={field.onChange}
                                                        />
                                                    )}
                                                />
                                                <Label htmlFor={`field-${idx}-required`} className="cursor-pointer">Required</Label>
                                            </div>
                                            <Button
                                                variant="ghost"
                                                type="button"
                                                size="icon"
                                                className="self-center text-destructive hover:bg-destructive/10"
                                                onClick={() => remove(idx)}
                                                tabIndex={-1}
                                                aria-label="Delete Field"
                                            >
                                                <Trash2 className="w-5 h-5" />
                                            </Button>
                                        </div>
                                    </div>
                                    <div className="grid md:grid-cols-2 gap-4 mt-3">
                                        {/* For Relation */}
                                        {watchedFields?.[idx]?.type === "relation" && (
                                            <div className="flex gap-4 items-end">
                                                <div className="flex-1 grid gap-2">
                                                    <Label>Related Type</Label>
                                                    <Controller
                                                        control={control}
                                                        name={`fields.${idx}.relation.target` as const}
                                                        render={({ field }) => (
                                                            <Select value={field.value} onValueChange={field.onChange}>
                                                                <SelectTrigger className="w-full">
                                                                    <SelectValue placeholder="Select content type" />
                                                                </SelectTrigger>
                                                                <SelectContent>
                                                                    {contentTypeOptions.map(opt => (
                                                                        <SelectItem key={opt.value} value={opt.value}>
                                                                            {opt.label}
                                                                        </SelectItem>
                                                                    ))}
                                                                </SelectContent>
                                                            </Select>
                                                        )}
                                                    />
                                                </div>
                                                <div className="flex-1 grid gap-2">
                                                    <Label>Relation Type</Label>
                                                    <Controller
                                                        control={control}
                                                        name={`fields.${idx}.relation.relationType` as const}
                                                        render={({ field }) => (
                                                            <Select value={field.value} onValueChange={field.onChange}>
                                                                <SelectTrigger className="w-full">
                                                                    <SelectValue placeholder="Select type" />
                                                                </SelectTrigger>
                                                                <SelectContent>
                                                                    <SelectItem value="one-one">
                                                                        One-to-One
                                                                    </SelectItem>
                                                                    <SelectItem value="one-many">
                                                                        One-to-Many
                                                                    </SelectItem>
                                                                    <SelectItem value="many-many">
                                                                        Many-to-Many
                                                                    </SelectItem>
                                                                </SelectContent>
                                                            </Select>
                                                        )}
                                                    />
                                                </div>
                                            </div>
                                        )}
                                        {/* For Options */}
                                        {(watchedFields?.[idx]?.type === "select" ||
                                            watchedFields?.[idx]?.type === "radio") && (
                                                <div className="space-y-2">
                                                    <Label>Options</Label>
                                                    <Controller
                                                        control={control}
                                                        name={`fields.${idx}.options` as const}
                                                        render={({ field: optionsField }) => (
                                                            <div className="flex flex-col items-start gap-2">
                                                                {(optionsField.value || []).map((opt: FieldOption, optIdx: number) => (
                                                                    <div key={optIdx} className="flex gap-2 items-center">
                                                                        <Input
                                                                            placeholder="Option label"
                                                                            value={opt.label}
                                                                            onChange={e =>
                                                                            {
                                                                                const opts = [...(optionsField.value || [])]
                                                                                opts[optIdx].label = e.target.value
                                                                                opts[optIdx].value = e.target.value
                                                                                optionsField.onChange(opts)
                                                                            }}
                                                                        />
                                                                        <Button
                                                                            type="button"
                                                                            variant="outline"
                                                                            size="icon"
                                                                            onClick={() =>
                                                                            {
                                                                                const opts = [...(optionsField.value || [])]
                                                                                opts.splice(optIdx, 1)
                                                                                optionsField.onChange(opts)
                                                                            }}
                                                                        >
                                                                            <Trash2 className="w-4 h-4" />
                                                                        </Button>
                                                                    </div>
                                                                ))}
                                                                <Button
                                                                    type="button"
                                                                    variant="outline"
                                                                    size="sm"
                                                                    className="mt-1"
                                                                    onClick={() => optionsField.onChange([...(optionsField.value || []), { label: "", value: "" }])}
                                                                >
                                                                    + Add Option
                                                                </Button>
                                                            </div>
                                                        )}
                                                    />
                                                </div>
                                            )}

                                        {/* For Slug field */}
                                        {watchedFields?.[idx]?.type === "slug" && (
                                            <div className="flex flex-col gap-2 mt-2 md:col-span-10">
                                                <Label>Slug Source</Label>
                                                <Controller
                                                    control={control}
                                                    name={`fields.${idx}.slugSource` as const}
                                                    render={({ field }) => (
                                                        <Select value={field.value} onValueChange={field.onChange}>
                                                            <SelectTrigger className="min-w-[200px]">
                                                                <SelectValue placeholder="Select source field" />
                                                            </SelectTrigger>
                                                            <SelectContent>
                                                                {fields
                                                                    .filter(f =>
                                                                        (f.type === "text" ||
                                                                            f.type === "textarea" ||
                                                                            f.type === "richtext") &&
                                                                        f.name // Filter out fields with no name
                                                                    )
                                                                    .map(f => (
                                                                        <SelectItem key={f.name} value={f.name}>
                                                                            {f.label}
                                                                        </SelectItem>
                                                                    ))}
                                                            </SelectContent>
                                                        </Select>
                                                    )}
                                                />
                                            </div>
                                        )}
                                    </div>
                                    <div className="border-b mt-8" />
                                </div>
                            ))}
                        </div>
                    </section>
                    <div className="flex justify-end">
                        <Button type="submit" disabled={submitting} className="h-auto px-8 py-3 text-base cursor-pointer">
                            {submitting ? "Saving..." : "Create Content Type"}
                        </Button>
                    </div>
                    {apiError && (
                        <div className="text-red-600 font-medium text-center pt-2">{apiError}</div>
                    )}
                    {submitted && (
                        <div className="text-green-600 font-medium text-center pt-2">
                            Content type created successfully!
                        </div>
                    )}
                </form>
            </div>

            {isRestarting && (
                <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50">
                    <div className="bg-white dark:bg-zinc-900 p-6 rounded-xl flex flex-col items-center gap-4">
                        <Spinner className="w-8 h-8" />
                        <div className="text-lg font-semibold">Updating schema & restarting server…</div>
                        <div className="text-xs text-muted-foreground">The app will reload in a few seconds.</div>
                    </div>
                </div>
            )}
        </div>
    )
}
